package com.violet.service.manager.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.violet.domain.emuns.OrderStatus;
import com.violet.domain.po.*;
import com.violet.domain.result.ResultPage;
import com.violet.domain.search.MyPage;
import com.violet.domain.search.manager.MOrderSearch;
import com.violet.domain.vo.manager.MOrderVo;
import com.violet.mapper.*;
import com.violet.service.manager.MOrderService;
import com.violet.utils.OrderUtils;
import com.violet.utils.SearchUtils;
import com.violet.utils.TransitionUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

@Service
@RequiredArgsConstructor
public class MOrderServiceImpl extends ServiceImpl<BuyOrderMapper, BuyOrder>
        implements MOrderService {

    private final TransitionUtils<?, BuyOrder, MOrderVo> orderT;
    private final TransitionUtils<?, User, MOrderVo.MOrderUser> userT;
    private final TransitionUtils<?, Rider, MOrderVo.MOrderRider> riderT;
    private final TransitionUtils<?, BuyAddress, MOrderVo.MOrderAddress> addressT;
    private final TransitionUtils<?, BuyProduct, MOrderVo.MOrderProduct> productT;

    private final UserMapper userMapper;
    private final RiderMapper riderMapper;
    private final BuyAddressMapper addressMapper;
    private final BuyProductMapper productMapper;

    private final OrderUtils orderUtils;

    @Override
    public ResultPage<List<MOrderVo>> search(MOrderSearch search, MyPage myPage) {
        Page<BuyOrder> page = new Page<>(myPage.getCurrentPage(), myPage.getPageSize());
        // 分页拿到订单
        baseMapper.selectPage(page, SearchUtils.getSearchWrapper(search));
        List<MOrderVo> result = new ArrayList<>();
        // 封装 VO
        for (BuyOrder order : page.getRecords()) {
            // 转 VO
            MOrderVo vo = orderT.transition(order, MOrderVo.class);
            vo.setStatus(order.getStatus().message);
            // 封装用户
            User user = userMapper.selectById(order.getUserId());
            vo.setUser(userT.transition(user, MOrderVo.MOrderUser.class));
            // 封装收获地址（一个收获地址对应一个订单）
            BuyAddress address = addressMapper.selectOne(new LambdaQueryWrapper<BuyAddress>().eq(BuyAddress::getOrderId, order.getId()));
            vo.setAddress(addressT.transition(address, MOrderVo.MOrderAddress.class));
            // 封装商品（一个购买商品对应一个订单）
            List<BuyProduct> products = productMapper.selectList(new LambdaQueryWrapper<BuyProduct>().eq(BuyProduct::getOrderId, order.getId()));
            Stream<MOrderVo.MOrderProduct> stream = products.stream().map(product -> productT.transition(product, MOrderVo.MOrderProduct.class));
            vo.setProducts(stream.toList());
            // 封装骑手（订单不是待支付状态和待发货状态）
            if (order.getStatus() != OrderStatus.WAIT_PAID && order.getStatus() != OrderStatus.WAIT_DELIVERY) {
                Rider rider = riderMapper.selectById(order.getRideId());
                vo.setRider(riderT.transition(rider, MOrderVo.MOrderRider.class));
            }
            result.add(vo);
        }
        return ResultPage.success(result, "分页搜索", page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delivery(String orderId, String riderId) {
        BuyOrder order = baseMapper.getByIdWithPessimisticLock(orderId);
        if (order == null) throw new RuntimeException("订单不存在");
        Rider rider = riderMapper.selectById(riderId);
        if (rider == null) throw new RuntimeException("骑手不存在");
        order.setStatus(OrderStatus.WAIT_RECEIVING);
        order.setRideId(riderId);
        return baseMapper.updateById(order) == 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancel(String orderId) {
        BuyOrder order = baseMapper.getByIdWithPessimisticLock(orderId);
        if (order == null) throw new RuntimeException("订单不存在");
        // 不能取消已完成的订单
        if (order.getStatus() == OrderStatus.COMPLETED) throw new RuntimeException("订单已完成, 无法取消");
        // 取消订单
        return baseMapper.deleteById(orderId) == 1;
    }

    @Override
    public Boolean complete(String id) {
        BuyOrder order = baseMapper.selectById(id);
        if (order == null) throw new RuntimeException("订单不存在");
        // 只有配送中的订单才能完成
        if (order.getStatus() != OrderStatus.WAIT_RECEIVING) throw new RuntimeException("订单状态错误");
        // 确认订单完成
        return orderUtils.confirmReceivingOrder(id);
    }

}
